package org.hyh.core.security.Filter;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.hyh.core.model.entity.SysUser;
import org.hyh.core.model.vo.LoginVo;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @auther :hyh
 * @desc :
 * @date :2020/7/13
 */
public class CustomUsernamePasswordAuthenticationFilter  extends AbstractAuthenticationProcessingFilter {

    public CustomUsernamePasswordAuthenticationFilter() {
        super(new AntPathRequestMatcher("/login", "POST"));
    }

     //这里必须传入 successHandler/failureHandler 否则会使用父类默认的SavedRequestAwareAuthenticationSuccessHandler。
    public CustomUsernamePasswordAuthenticationFilter(String loginUrl,
                                                      AuthenticationManager authenticationManager,
                                                      AuthenticationSuccessHandler successHandler,
                                                      AuthenticationFailureHandler failureHandler) {
        super(new AntPathRequestMatcher(loginUrl, "POST"));
        setAuthenticationFailureHandler(failureHandler);
        setAuthenticationSuccessHandler(successHandler);
        setAuthenticationManager(authenticationManager);
    }




    /**
     *  从写此方法，从而实现ajax 请求登录。  正常情况下，是request#getParamter() 获取参数。重写从请求体中获取参数。
     * @param request
     * @param response
     * @return
     * @throws AuthenticationException
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        LoginVo loginVo = new ObjectMapper().readValue(request.getInputStream(), LoginVo.class);
        UsernamePasswordAuthenticationToken  authRequest=new UsernamePasswordAuthenticationToken(JSON.toJSONString(loginVo),loginVo.getPassword());
        setDetails(request, authRequest);
       return getAuthenticationManager().authenticate(authRequest);
    }

    protected void setDetails(HttpServletRequest request,
                              UsernamePasswordAuthenticationToken authRequest) {
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }
}
